﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Threading;
using Microsoft.Win32;
using System.Reflection;

namespace Coding4Fun.PrinterDisplayHack
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private DispatcherTimer _timer;
        private string _lastMessage = "";
        private Queue<LogEntry> _logs = new Queue<LogEntry>();
        private Boolean _settingsHaveChanged;

        public MainWindow()
        {
            InitializeComponent();

            _timer = new DispatcherTimer {Interval = TimeSpan.FromMilliseconds(1000*60*5)};
            _timer.Tick += (s, a) => SendTickerToPrinter();
        }

		private void GetPrice_Click(object sender, RoutedEventArgs e)
		{
			string result = GetStockPrice();
			LogText(rtfLog, result);
		}

        private void GetPrinter_Click(object sender, RoutedEventArgs e)
        {
            FindPrinters fp = new FindPrinters();

            bool? showDialog = fp.ShowDialog();
            Boolean dlgResult = showDialog != null && showDialog.Value;

            if (dlgResult)
                PrinterHackSettings.Default.PrinterAddress = fp.SelectedIpAddress;
        }

        private void btnExit_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            if (_settingsHaveChanged)
            {
                _settingsHaveChanged = false;

                StopPrinterHacking();

                PrinterHackSettings.Default.Save();

                StartWithWindows(PrinterHackSettings.Default.StartWithWindows);

                MessageBox.Show("Settings saved.", Properties.Resources.DisplayTitle, MessageBoxButton.OK, MessageBoxImage.Information);
            }

            StartPrinterHacking();

            this.Hide();
        }

        private void grid_Loaded(object sender, RoutedEventArgs e)
        {
            grid.DataContext = PrinterHackSettings.Default;

            PrinterHackSettings.Default.SettingChanging += SettingsChanged;
        }

        private void StartWithWindows(bool start)
        {
            using (RegistryKey hkcu = Registry.CurrentUser)
            {
                using (RegistryKey runKey = hkcu.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true))
                {
                    if (runKey == null)
                        return;

                    if (start)
                        runKey.SetValue(Properties.Resources.Code4FunStockPrinter, Assembly.GetEntryAssembly().Location);
                    else
                    {
                        if (runKey.GetValue(Properties.Resources.Code4FunStockPrinter) != null)
                            runKey.DeleteValue(Properties.Resources.Code4FunStockPrinter);
                    }
                }
            }
        }

		public Boolean SettingsAreValid()
		{
			return (!string.IsNullOrWhiteSpace(PrinterHackSettings.Default.PrinterAddress) && !string.IsNullOrWhiteSpace(PrinterHackSettings.Default.StockSymbol));
		}

		public void SendTickerToPrinter()
		{
			if (SettingsAreValid())
			{
				string message = GetStockPrice();

				if (message.Equals(_lastMessage))
					LogText(rtfLog, "No change");
				else
				{
					SendToPrinter sendToPrinter = new SendToPrinter { Host = PrinterHackSettings.Default.PrinterAddress };

					sendToPrinter.Send(message);

					LogText(rtfLog, message);
					_lastMessage = message;
				}
			}
		}

		public void UpdateLog(RichTextBox rtb)
		{
			int i = 0;

			foreach (LogEntry lg in _logs)
			{
				i++;
				TextRange tr = new TextRange(rtb.Document.ContentEnd, rtb.Document.ContentEnd) { Text = String.Format("{0} : ", lg.LogTime.ToString("hh:mm:ss")) };
				tr.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Red);

				tr = new TextRange(rtb.Document.ContentEnd, rtb.Document.ContentEnd) { Text = lg.LogMessage + Environment.NewLine };
				tr.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.White);
			}

			if (i > 10)
				_logs.Dequeue();

			rtb.ScrollToEnd();
		}

		public void LogText(string message)
		{
			LogText(rtfLog, message);
		}

		public void LogText(RichTextBox rtb, string message)
		{
			_logs.Enqueue(new LogEntry() { LogTime = DateTime.Now, LogMessage = message });

			UpdateLog(rtb);
		}

		private string GetStockPrice()
		{
			string tickerSymbol = PrinterHackSettings.Default.StockSymbol;
			if (!string.IsNullOrWhiteSpace(tickerSymbol))
			{
				StockPrice stockPrice = new StockPrice(tickerSymbol);
				string result;

				string lastTradedPrice = stockPrice.GetPrice();
				double currentPrice;

				if (Double.TryParse(lastTradedPrice, out currentPrice))
					result = String.Format("{0}: {1:C}", tickerSymbol, currentPrice);
				else
					result = String.Format("{0}: {1}", tickerSymbol, lastTradedPrice);

				return result;
			}

			return string.Empty;
		}

		public void StartPrinterHacking()
		{
			if (PrinterHackSettings.Default.Enabled)
			{
				SendTickerToPrinter();
				_timer.Start();
			}
		}

		public void StopPrinterHacking()
		{
			_timer.Stop();
		}

        void SettingsChanged(object sender, SettingChangingEventArgs e)
        {
            _settingsHaveChanged = true;
        }
    }
}
